package com.adamfass.tractorbeam;

import java.awt.BorderLayout;
import java.awt.Frame;

import javax.swing.JDialog;
import javax.swing.JTextArea;

import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import com.adamfass.jmeutil.Util;
import com.jme.input.InputSystem;
import com.jme.input.MouseInput;
import com.jme.input.joystick.Joystick;
import com.jme.input.joystick.JoystickInput;
import com.jmex.game.StandardGame;
import com.jmex.game.state.GameStateManager;

public class Main {
  
  private static boolean devMode;
  private static boolean showDiagnosticsAndExit;

  // TODO(afass): Dead code, move this somewhere else if I ever need it.
  private static boolean is4To3AspectRatio(DisplayMode mode) {
    return Math.abs(((double) mode.getWidth() / (double) mode.getHeight())
        - (4d / 3d)) < 0.1;
  }

  private static boolean isGoodMode(DisplayMode mode) {
    return ((mode.getWidth() == 320) && (mode.getHeight() == 200))
        || ((mode.getWidth() == 640) && (mode.getHeight() == 480))
        || ((mode.getWidth() == 800) && (mode.getHeight() == 600))
        || ((mode.getWidth() == 1024) && (mode.getHeight() == 768))
        || ((mode.getWidth() == 1280) && (mode.getHeight() == 1024))
        || ((mode.getWidth() == 1400) && (mode.getHeight() == 1050))
        || ((mode.getWidth() == 1600) && (mode.getHeight() == 1200));
  }
  
  private static void parseCommandLineArguments(String[] args) {
    for (String arg : args) {
      if (arg.equals("--dev_mode")) {
        devMode = true;
      } else if (arg.equals("--show_diagnostics_and_exit")) {
        showDiagnosticsAndExit = true;
      }
    }
  }
  
  private static void showDiagnosticsDialog(String diagnosticInfo) {
    final JDialog dialog = new JDialog((Frame) null, true);
    dialog.getContentPane().setLayout(new BorderLayout());
    dialog.getContentPane().add(new JTextArea(diagnosticInfo), BorderLayout.CENTER);
    dialog.pack();
    dialog.setVisible(true);
  }

  public static void main(String[] args) throws Exception {
    parseCommandLineArguments(args);
    
    JoystickInput.setProvider(InputSystem.INPUT_SYSTEM_LWJGL);

    StandardGame game = new StandardGame("Tractor Beam Ball");

    String diagnosticInfo = getDiagnosticInfo();
    System.out.println(diagnosticInfo);
    if (showDiagnosticsAndExit) {
      showDiagnosticsDialog(diagnosticInfo);
      System.exit(0);
    }
    
    final boolean cursorVisible;
    final boolean fullScreen;
    final int displayWidth;
    final int displayHeight;

    if (devMode) {
      fullScreen = false;
      cursorVisible = true;
      displayWidth = 800;
      displayHeight = 600;
    } else if (System.getProperty("os.name").equals("Linux")) {
      fullScreen = false;
      cursorVisible = true;
      displayWidth = 1024;
      displayHeight = 768;
    } else {
      DisplayMode bestMode = null;
      int maxWidth = 0;
      for (DisplayMode mode : Display.getAvailableDisplayModes()) {
        if ((mode.getWidth() > maxWidth) && isGoodMode(mode)) {
          bestMode = mode;
          maxWidth = bestMode.getWidth();
        }
      }
      fullScreen = true;
      displayWidth = bestMode.getWidth();
      displayHeight = bestMode.getHeight();
      cursorVisible = false;
    }

    game.getSettings().setFullscreen(fullScreen);
    game.getSettings().setWidth(displayWidth);
    game.getSettings().setHeight(displayHeight);

    game.start();

    final MenuGameState menuGameState = new MenuGameState(
        new MenuGameState.MenuGameStateListener() {
          public void handleBeginGame(GameFlow gameFlow) {
            MainGameState mainGameState = new MainGameState(gameFlow);
            GameStateManager.getInstance().attachChild(mainGameState);
            mainGameState.setActive(true);
          }
        });

    GameStateManager.getInstance().attachChild(menuGameState);
    menuGameState.setActive(true);

    MouseInput.get().setCursorVisible(cursorVisible);
  }
  
  public static String getDiagnosticInfo() {
    final StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append("os.name=" + System.getProperty("os.name") + "\n");
    stringBuilder.append("os.arch=" + System.getProperty("os.arch") + "\n");
    stringBuilder.append("os.version=" + System.getProperty("os.version") + "\n");
    
    final int joystickCount = JoystickInput.get().getJoystickCount();
    stringBuilder.append("Number of joysticks: " + joystickCount + "\n");
    for (int i = 0; i < joystickCount; i++) {
      final Joystick joystick = JoystickInput.get().getJoystick(i);
      stringBuilder.append("  joystick: " + joystick.getName() + "\n");
      for (String axisName : joystick.getAxisNames()) {
        stringBuilder.append("    axis: " + axisName + "\n");
      }
    }
    
    stringBuilder.append("Real Joysticks:\n");
    for (Joystick joystick : Util.getRealJoysticks(JoystickInput.get())) {
      stringBuilder.append("  joystick: " + joystick.getName() + "\n");
      for (String axisName : joystick.getAxisNames()) {
        stringBuilder.append("    axis: " + axisName + "\n");
      }
    }
    
    return stringBuilder.toString();
  }
}
